package com.ebt.m.utils.fileutils;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.StatFs;
import android.provider.MediaStore;
import android.util.Log;

import com.ebt.m.R;
import com.ebt.m.data.bean.EbtFile;
import com.ebt.m.repository.provider.FileIconHelper;
import com.ebt.m.repository.provider.FileTypeHelper;
import com.ebt.m.utils.MIMETypes;
import com.ebt.m.utils.UriUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件操作类
 *
 * @author damon.han
 */
public class FileUtils {
    private static int INSTALLED = 0; // 表示已经安装，且跟现在这个apk文件是一个版本
    private static int UNINSTALLED = 1; // 表示未安装
    private static int INSTALLED_UPDATE = 2; // 表示已经安装，版本比现在这个版本要低

    /**
     * 检查文件后缀名
     *
     * @param checkItsEnd
     * @param fileEndings
     * @return
     */
    public static boolean checkEndsWithInStringArray(String checkItsEnd, String[] fileEndings) {
        if (checkItsEnd == null || fileEndings == null) {
            return false;
        }
        if (checkItsEnd.lastIndexOf(".") == -1) {
            return false;
        }
        String end = checkItsEnd.substring(checkItsEnd.lastIndexOf("."), checkItsEnd.length());
        for (String aEnd : fileEndings) {
            if (end.equalsIgnoreCase(aEnd)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获得文件大小表示
     */
    public static String formatFileSize(long len) {
        if (len < 1024) {
            return len + " B";
        } else if (len < 1024 * 1024) {
            return len / 1024 + "." + (len % 1024 / 10 % 100) + " KB";
        } else if (len < 1024 * 1024 * 1024) {
            return len / (1024 * 1024) + "." + len % (1024 * 1024) / 10 % 100 + " MB";
        } else {
            return len / (1024 * 1024 * 1024) + "." + len % (1024 * 1024 * 1024) / 10 % 100 + " G";
        }
    }

    /**
     * 根据路径获得文件名
     *
     * @param path
     * @return
     */
    public static String getFileName(String path) {
        if (path == null || path.equals("") || !path.contains(File.separator)) {
            return "";
        }
        return path.substring(path.lastIndexOf(File.separator) + 1, path.length());
    }

    /**
     * 缩放图片
     *
     * @param b
     * @param newWidth
     * @param newHeight
     * @return
     */
    public static Bitmap zoomImage(Bitmap b, int newWidth, int newHeight) {
        int width = b.getWidth();
        int height = b.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix
        Matrix matrix = new Matrix();
        matrix.setScale(scaleWidth, scaleHeight);
        // 获得新图片
        Bitmap newB = Bitmap.createBitmap(b, 0, 0, width, height, matrix, true);
        return newB;
    }

    // 获取文件头信息
    public static String getFileHeader(String filePath) {
        FileInputStream is = null;
        String value = null;
        try {
            is = new FileInputStream(filePath);
            byte[] b = new byte[3];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
        } catch (Exception e) {
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        return value;
    }

    /**
     * 获得文件内容的mime十六进制内容
     *
     * @param src
     * @return
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        String hv;
        for (int i = 0; i < src.length; i++) {
            hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }

    /**
     * 根据文件的后缀名获得文件类型
     *
     * @param filePath
     * @return 文件类型码
     */
    @Deprecated
    public static int getFileTypeBySuffix(String filePath, Context context) {
        int type = 0;
        // int type = ConfigData.FILE_TYPE_NULL;
        // if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingImage))) {
        // type = ConfigData.FILE_TYPE_IMAGE;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingAudio))) {
        // type = ConfigData.FILE_TYPE_AUDIO;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingVideo))) {
        // type = ConfigData.FILE_TYPE_VIDEO;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingPPT))) {
        // type = ConfigData.FILE_TYPE_PPT;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingWord))) {
        // type = ConfigData.FILE_TYPE_WORD;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingExcel))) {
        // type = ConfigData.FILE_TYPE_EXCEL;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingApk))) {
        // type = ConfigData.FILE_TYPE_APK;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingPdf))) {
        // type = ConfigData.FILE_TYPE_PDF;
        // } else if (FileUtils.checkEndsWithInStringArray(filePath,
        // context.getResources().getStringArray(R.array.fileEndingWebText))) {
        // type = ConfigData.FILE_TYPE_WEB;
        // }
        return type;
    }

    public static int[] getImageWidthAndHeight(String imagePath) {
        int[] result = new int[2];
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        // 获取图片的宽和高，这里的bitmap并没有加载到内存为null
        int w = options.outWidth;
        int h = options.outHeight;
        result[0] = w;
        result[1] = h;
        return result;
    }

    /**
     * @param path      -原始路径
     * @param desWidth  --目标宽度
     * @param desHeight --目标高度
     * @return
     */
    public static Bitmap getImageThumbnail(String path, int desWidth, int desHeight) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;// 设置成了true,不占用内存，只获取bitmap宽高
        BitmapFactory.decodeFile(path, opts);
        int minSize = desWidth < desHeight ? desWidth : desHeight;
        opts.inSampleSize = computeSampleSize(opts, minSize, 2048 * 1280);
        opts.inJustDecodeBounds = false;// 这里一定要将其设置回false，因为之前我们将其设置成了true
        opts.inPurgeable = true;
        opts.inInputShareable = true;
        opts.inDither = false;
        opts.inPurgeable = true;
        opts.inTempStorage = new byte[16 * 1024];
        opts.inPreferredConfig = Bitmap.Config.RGB_565;// 低颜色数
        FileInputStream is = null;
        Bitmap bmp = null;
        try {
            is = new FileInputStream(path);
            bmp = BitmapFactory.decodeFileDescriptor(is.getFD(), null, opts);
            double scale = getScaling(opts.outWidth * opts.outHeight, desWidth * desHeight);
            Bitmap bmp2 = Bitmap.createScaledBitmap(bmp, (int) (opts.outWidth * scale), (int) (opts.outHeight * scale), true);
            // ByteArrayOutputStream bos = new ByteArrayOutputStream();
            // 试验生成图片的大小
            // FileOutputStream baos = new FileOutputStream(new
            // File(ConfigData.DATA_PATH + "/aaa.png"));
            // bmp2.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            // // bmp2.recycle();
            // bmp.recycle();
            return bmp2;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            // System.gc();
        }
        return null;
        // 单纯使用工具类会大小不合适
        // Bitmap b =
        // ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(path),
        // desWidth, desHeight, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        // FileOutputStream baos= null;
        // try {
        // baos = new FileOutputStream(new File(ConfigData.DATA_PATH +
        // "/aaa.png"));
        // } catch (FileNotFoundException e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        // b.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        // return b;
    }

    /**
     * 获取视频的缩略图 先通过ThumbnailUtils来创建一个视频的缩略图，然后再利用ThumbnailUtils来生成指定大小的缩略图。
     * 如果想要的缩略图的宽和高都小于MICRO_KIND，则类型要使用MICRO_KIND作为kind的值，这样会节省内存。
     *
     * @param videoPath 视频的路径
     * @param width     指定输出视频缩略图的宽度
     * @param height    指定输出视频缩略图的高度度
     * @param kind      参照MediaStore.Images.Thumbnails类中的常量MINI_KIND和MICRO_KIND。
     *                  其中，MINI_KIND: 512 x 384，MICRO_KIND: 96 x 96
     * @return 指定大小的视频缩略图
     */
    public static Bitmap getVideoThumbnail(String videoPath, int width, int height, int kind) {
        Bitmap bitmap = null;
        // 获取视频的缩略图
        bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
        // bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
        // ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }

    /**
     * compute Sample Size
     *
     * @param options
     * @param minSideLength
     * @param maxNumOfPixels
     * @return
     */
    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    /**
     * compute Initial Sample Size
     *
     * @param options
     * @param minSideLength
     * @param maxNumOfPixels
     * @return
     */
    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }


    /**
     * 复制文件
     *
     * @param target -目标文件
     */
    public static void copyFile(File source, File target) {
        if (source == null) {
            return;
        }
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(source));
            bos = new BufferedOutputStream(new FileOutputStream(target));
            byte[] b = new byte[1024 * 5];
            int length;
            while ((length = bis.read(b)) != -1) {
                bos.write(b, 0, length);
            }
            bos.flush();
        } catch (Exception e) {
            return;
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    /*
     * 复制文件夹包含其中的文件
     */
    public static void copyDir(String sourceDir, String targetDir) {
        if (targetDir == null) {
            return;
        }
        File t = new File(targetDir);
        if (!t.canWrite()) {
            return;
        }
        t.mkdirs();

        File[] file = (new File(sourceDir)).listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                File sourceFile = file[i];
                File targetFile = new File(new File(targetDir).getAbsolutePath() + File.separator + file[i].getName());
                copyFile(sourceFile, targetFile);
            } else if (file[i].isDirectory()) {
                String dir1 = sourceDir + File.separator + file[i].getName();
                String dir2 = targetDir + File.separator + file[i].getName();
                copyDir(dir1, dir2);
            }
        }
    }

    /**
     * 删除目标文件或者文件夹
     *
     * @param filePath
     */
    public static boolean del(String filePath) {
        File f = new File(filePath);
        if (!f.canWrite()) {
            return false;
        }
        if (f.exists() && f.isDirectory()) {

            if (f.listFiles().length == 0) {// 若目录下没有文件则直接删除
                f.delete();

            } else {

                File delFile[] = f.listFiles();
                int i = f.listFiles().length;
                for (int j = 0; j < i; j++) {
                    if (delFile[j].isDirectory()) {
                        del(delFile[j].getAbsolutePath());
                    }
                    delFile[j].delete();
                }
            }
        } else if (f.exists() && f.isFile()) {
            f.delete();
        }
        return true;
    }

    /**
     * 获得缩放比例-(用于图片缩放)
     *
     * @param src
     * @param des
     * @return
     */
    private static double getScaling(int src, int des) {
        /**
         * 目标尺寸÷原尺寸 sqrt开方，得出宽高百分比
         */
        double scale = Math.sqrt((double) des / (double) src);
        return scale;
    }

    /**
     * 判断是否自身
     *
     * @param packageName
     * @return
     */
    public static boolean isMine(Context context, String packageName) {
        if (packageName == null) {
            return false;
        }
        if (packageName.contains("com.ebt.app")) {
            return true;
        }
        return false;
    }

    /**
     * 获取应用程序的图标
     *
     * @param context
     * @param packageName -包名
     * @param className   -类名
     * @return
     */
    public static Drawable getAppIcon(Context context, String packageName, String className) {
        Drawable icon = null;
        PackageManager pkgMgr = context.getPackageManager();
        try {
            ComponentName cn = new ComponentName(packageName, className);
            icon = pkgMgr.getActivityIcon(cn);
        } catch (Exception e) {
            Log.w("getAppIcon", packageName + "获取应用程序图标异常");
            e.printStackTrace();
        }
        return icon;
    }

    /**
     * @param context
     * @param path    -apk文件绝对路径
     * @return
     */
    public static Drawable getApkIcon(Context context, String path) {
        Drawable icon = null;
        PackageManager pm = context.getPackageManager();
        PackageInfo packageInfo = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
        try {
            if (packageInfo != null) {
                ApplicationInfo appInfo = packageInfo.applicationInfo;
                if (appInfo != null) {
                    appInfo.sourceDir = path;
                    appInfo.publicSourceDir = path;
                    icon = appInfo.loadIcon(pm);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return icon;
    }

    /**
     * @param
     * @return void
     * @throws
     * @Description: 复制文件
     */
    public static void transferCopy(File source, File target) {
        FileChannel in = null;
        FileChannel out = null;
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(source);
            fos = new FileOutputStream(target);
            in = fis.getChannel();
            out = fos.getChannel();
            in.transferTo(0, in.size(), out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @param packageName
     * @param versionCode
     * @return int
     * @throws
     */
    public static int getAPKState(PackageManager pm, String packageName, int versionCode) {
        List<PackageInfo> list = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
        for (PackageInfo info : list) {
            String pName = info.packageName;
            int pVersionCode = info.versionCode;
            if (packageName.endsWith(pName)) {
                // 如果这个包名在系统已经安装过的应用中存在
                // Log.i("test","此应用安装过了");
                if (versionCode == pVersionCode) {
                    // Log.i("test", "已经安装，不用更新，可以卸载该应用");
                    return INSTALLED;
                } else if (versionCode > pVersionCode) {
                    // Log.i("test", "已经安装，有更新");
                    return INSTALLED_UPDATE;
                }
            }
        }
        Log.i("test", "未安装该应用，可以安装");
        return UNINSTALLED;
    }

    /**
     * 获取调用系统自带文件管理器选中的文件的路径
     *
     * @param context
     * @param uri
     * @return
     */
    public static String getPath(Context context, Uri uri) {

        if ("content".equalsIgnoreCase(uri.getScheme())) {

            String[] projection = {"_data"};

            Cursor cursor = null;

            try {

                cursor = context.getContentResolver().query(uri, projection, null, null, null);

                int column_index = cursor.getColumnIndexOrThrow("_data");

                if (cursor.moveToFirst()) {

                    return cursor.getString(column_index);

                }

            } catch (Exception e) {

                // Eat it

            }

        } else if ("file".equalsIgnoreCase(uri.getScheme())) {

            return uri.getPath();

        }

        return null;

    }

    public static String getMimeType(String fileName) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String type = fileNameMap.getContentTypeFor(fileName);
        return type;
    }

    /**
     * 获得正方形缩略图
     *
     * @param type
     * @return
     */
    public static int getSquareThumb(FileTypeHelper.FileTypeAll type) {
        int result = 0;
        switch (type) {
            case FILE_TYPE_AUDIO:// audio
                result = R.drawable.thumb_square_audio_128;
                break;
            case FILE_TYPE_EXCEL:// excel
                result = R.drawable.thumb_square_excel_128;
                break;
            case FILE_TYPE_PPT:// ppt
                result = R.drawable.thumb_square_ppt_128;
                break;
            case FILE_TYPE_WORD:// word
                result = R.drawable.thumb_square_word_128;
                break;
            case FILE_TYPE_TEXT://
                result = R.drawable.thumb_square_txt_128;
                break;
            case FILE_TYPE_PDF:// pdf
                result = R.drawable.thumb_square_pdf_128;
                break;
            case FILE_TYPE_WEB:// web
                result = R.drawable.thumb_square_web_128;
                break;
            case FILE_TYPE_FOLDER:// folder
                result = R.drawable.thumb_rect_folder;
                break;
            default:
                result = R.drawable.thumb_square_null_128;
                break;
        }
        return result;
    }

    public static EbtFile convertFileToEbtFile(File file) {
        EbtFile ebtFile = new EbtFile();
        ebtFile.name = file.getName();
        ebtFile.path = file.getPath();
        ebtFile.size = file.length();
        ebtFile.type = FileIconHelper.getFileTypeBySuffix(file.getPath());
        // may not used
        ebtFile.canRead = file.canRead();
        ebtFile.canWrite = file.canWrite();
        ebtFile.isFolder = file.isDirectory();
        ebtFile.isHidden = file.isHidden();
        ebtFile.lastModify = file.lastModified();

        return ebtFile;
    }

    public static String getStringFromInputStream(InputStream is)
            throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // 模板代码 必须熟练
        byte[] buffer = new byte[1024];
        int len = -1;
        // 一定要写len=is.read(buffer)
        // 如果while((is.read(buffer))!=-1)则无法将数据写入buffer中
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        is.close();
        String state = os.toString();// 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
        os.close();
        return state;
    }

    /**
     * 通用打开文件方法
     *
     * @param context
     * @param file
     */
    public static void openFile(Context context, File file) throws Exception {
        Intent intent = new Intent();
        intent.addCategory("android.intent.category.DEFAULT");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(android.content.Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        String type = MIMETypes.getMimeType(file);
        Uri uri = UriUtils.getUriFromFile(file);
        intent.setDataAndType(uri, type);
        context.startActivity(intent);

    }

    public final static Map<String, String> FILE_TYPE_MAP_RES = new HashMap<String, String>();
    public final static Map<String, String> FILE_TYPE_MAP_NEW = new HashMap<String, String>();

    static {
        getAllFileType();
        getAllFileMapingType();
        // 初始化文件类型信息
    }

    /**
     * 将常见文件类型映射自定义文件类型
     */
    private static void getAllFileType() {
        FILE_TYPE_MAP_NEW.put("jpg", "gpc"); // JPEG (jpg)
        FILE_TYPE_MAP_NEW.put("png", "gnc"); // PNG (png)
        FILE_TYPE_MAP_NEW.put("html", "hte"); // HTML (html)
        FILE_TYPE_MAP_NEW.put("xml", "xml"); // xml
        FILE_TYPE_MAP_NEW.put("rmvb", "romv"); // rmvb
        FILE_TYPE_MAP_NEW.put("mp3", "mp3"); // mp3
        FILE_TYPE_MAP_NEW.put("mp4", "mp4"); // mp4
    }

    /**
     * 将自定义文件类型映射为常见文件类型
     */
    private static void getAllFileMapingType() {
        FILE_TYPE_MAP_RES.put("gpc", "jpg"); // JPEG (jpg)
        FILE_TYPE_MAP_RES.put("gnc", "png"); // PNG (png)
        FILE_TYPE_MAP_RES.put("hte", "html"); // HTML (html)
        FILE_TYPE_MAP_RES.put("xml", "xml"); // xml
        FILE_TYPE_MAP_RES.put("romv", "rmvb"); // rmvb
        FILE_TYPE_MAP_RES.put("mp3", "mp3"); // mp3
        FILE_TYPE_MAP_RES.put("mp4", "mp4"); // mp4
    }

    /**
     * 获取路径下的可用空间
     *
     * @param directoryPath
     * @return
     */
    public static long getFreeSpaceAtDirectory(String directoryPath) {
        File path = new File(directoryPath);
        if (!path.exists()) {
            return -1;
        }
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long availableBlocks = stat.getAvailableBlocks();
        return availableBlocks * blockSize;
    }

    /**
     * 获取映射的自定义文件类型
     *
     * @param type
     * @return
     */
    public static String getMapingFileType(String type) {

        String newType = FILE_TYPE_MAP_NEW.get(type.toLowerCase());
        if (newType == null) {
            return type;
        } else {
            return newType;
        }

    }

    /**
     * 根据映射的文件类型，获取原文件类型
     *
     * @param mapingType 映射的文件类型
     * @return
     */
    public static String getFileType(String mapingType) {
        String oldType = FILE_TYPE_MAP_NEW.get(mapingType.toLowerCase());
        if (oldType == null) {
            return mapingType;
        } else {
            return oldType;
        }


    }

    /**
     * 判断文件夹是否存在，如果不存在，则创建
     *
     * @param filePath
     */
    public static void creatFile(String filePath) {
        File fileDir = new File(filePath);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
    }


    public static String getAbsoluteFileName(String path) {
        return path.substring(path.lastIndexOf("/") + 1, path.length());
    }

    /**
     * 解析文件后缀
     *
     * @param String
     *            fullPath
     *
     * @return fileType
     */
    /*
     * public static String getNowFileType(String fullPath) { String fileType =
     * fullPath.substring(fullPath.lastIndexOf('.')+1); return fileType; }
     */

    /**
     * 解析文件路径
     *
     * @param fullPath
     * @return filePath
     */
    public static String getFilePath(String fullPath) {
        String filePath = fullPath.substring(0, fullPath.lastIndexOf("/"));
        return filePath;
    }

    /**
     * 判断文件是否存在
     *
     * @param flie
     * @return boolean
     */
    public static boolean isFileExists(File flie) {
        return flie.exists();
    }

    /**
     * 更改文件名称
     *
     * @param oldfile,String newFile
     */
    public static void changeFileName(String oldfile, String newFileStr) {

        File file = new File(oldfile);
        File newfile = new File(newFileStr);
        if (newfile.exists()) {
            newfile.delete();
        }
        file.renameTo(new File(newFileStr));

    }

    /**
     * 删除指定文件(包含空文件夹)
     *
     * @param file
     */
    public static void deleteFile(File file) {
        if (file.exists()) { // 判断文件是否存在
            if (file.isFile()) { // 判断是否是文件
                file.delete(); // 删除
            } else if (file.isDirectory()) { // 否则如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    deleteFile(files[i]); // 把每个文件 用这个方法进行迭代
                }
            }
            file.delete();
        }
    }

    /**
     * 删除指定文件(包含空文件夹)
     *
     * @param filePath
     */
    public static void deleteFile(String filePath) {
        File file = new File(filePath);
        deleteFile(file);
    }

    /**
     * 获取文件后缀,包含.
     *
     * @param fileName 文件地址
     * @return 文件后缀
     */
    public static String getSuffixFromUrl(String fileName) {

        if (fileName == null || fileName.trim().length() == 0) {
            return null;
        }
        String suffix = ".tmp";
        try {
            // 获取后缀
            if (fileName.lastIndexOf(".") != -1) {
                suffix = fileName.substring(fileName.lastIndexOf("."));
                if (suffix.indexOf("/") != -1 || suffix.indexOf("?") != -1
                        || suffix.indexOf("&") != -1) {
                    suffix = null;
                }
            }
            if (suffix == null) {
                // 获取文件名
                if (fileName != null && fileName.lastIndexOf(".") != -1) {
                    suffix = fileName.substring(fileName.lastIndexOf("."));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return suffix;
    }

    /**
     * 复制文件
     *
     * @param input      -输入流
     * @param targetPath
     */
    public static void copyFile(InputStream input, String targetPath) {
        BufferedOutputStream bos = null;
        try {
            if (input == null || targetPath == null || targetPath.equals("")) {
                return;
            }
            bos = new BufferedOutputStream(new FileOutputStream(targetPath));
            byte[] b = new byte[1024 * 5];
            int length;
            while ((length = input.read(b)) != -1) {
                bos.write(b, 0, length);
            }
            bos.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 是否有子目录
     *
     * @return
     */
    public static boolean hasDirs(File file) {
        boolean hasDirs = false;
        File[] fs = file.listFiles();
        if (fs != null && fs.length > 0) {
            for (File file2 : fs) {
                if (file2 != null && file2.isDirectory()) {
                    hasDirs = true;
                    break;
                }
            }
        }
        return hasDirs;
    }

    public static boolean nioTransferCopy(File source, File target) {
        boolean ret = false;
        if (target == null) {
            return ret;
        } else {
            File parentFile = target.getParentFile();
            if (parentFile != null) {
                if (!parentFile.exists()) {
                    parentFile.mkdirs();
                }
            }
        }

        FileChannel in = null;
        FileChannel out = null;
        FileInputStream inStream = null;
        FileOutputStream outStream = null;
        try {
            inStream = new FileInputStream(source);
            outStream = new FileOutputStream(target);
            in = inStream.getChannel();
            out = outStream.getChannel();
            in.transferTo(0, in.size(), out);
            ret = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            close(inStream);
            close(in);
            close(outStream);
            close(out);
        }
        return ret;
    }

    private static void close(Object o) {
        if (o == null) {
            return;
        }
        try {
            if (o instanceof Closeable) {
                ((Closeable) o).close();
            }
        } catch (Exception e) {

        }
    }

    /**
     * 扫描本地文件到系统图库
     *
     * @param context
     * @param file    - 图片文件
     */
    public static void scanImageFile(Context context, File file) {
        Uri uri = null;
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), file.getName(), null);
            //通知图库更新
            uri = UriUtils.getUriFromFile(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (uri == null) {
            return;
        }
        Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
        context.sendBroadcast(localIntent);
    }
}
